<?php

namespace App\Http\Middleware;

use App\Models\Domain;
use App\Models\EasyWechat;
use App\Models\Member;
use App\Models\SettingsCache;
use App\Models\UniqidOpenid;
use App\Models\WechatMember;
use Closure;
use EasyWeChat\Foundation\Application;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Session;

class WechatOauth
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $path = $request->path();
        if ((!((int) SettingsCache::get('is_running', 1))) && 'wechat/not-running' != $path) {
            return redirect('/wechat/not-running');
        }
        if (!isset($_SERVER['HTTP_USER_AGENT'])) {
            die;
        }
        if ((!(strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger')) > 0) && !in_array($path, ['wechat/upload', 'wechat/payment/notify', 'wechat/api', 'wechat/qiniu/upload-token', 'wechat/qiniu/prefop', 'wechat/set-price', 'wechat/reward'])) {
            die('Browser This Page in Wechat Please');
        }
        // 直接跳转，不需要任何判断
        if (in_array($path, ['wechat/api', 'wechat/oauth', 'wechat/payment/notify', 'wechat/not-running'])) {
            return $next($request);
        }
        $currentDomain = $request->getHttpHost();
        $wechatDomain = SettingsCache::get('WECHAT_DOMAIN');
        // 查看视频界面不能用原始域名
        if ($path == 'wechat/view' && $currentDomain == $wechatDomain) {
            $domain = Domain::one();
            $redirectUrl = "http://{$domain}/wechat/view?id=" . $request->id
                . '&wechat_uniqid=' . Session::get('wechat_uniqid');
            return redirect($redirectUrl);
        }
        // 支付界面一定要用原始域名
        if ($path == 'wechat/payment/paying' && $currentDomain != $wechatDomain) {
            $redirectUrl = "http://{$wechatDomain}/wechat/payment/paying?id=" . $request->id
                . '&wechat_uniqid=' . Session::get('wechat_uniqid')
                . '&domain=' . $currentDomain
                . '&price=' . $request->price
                . '&_=' . $request->_;
            return redirect($redirectUrl);
        }
        // 准备用户身份信息
        $this->prepare($request);
        if (!empty($request->wechat_uniqid)) {
            $url = "http://{$currentDomain}/{$path}";
            $params = '';
            foreach ($request->all() as $k => $v) {
                if ($k == 'wechat_uniqid') {
                    continue;
                }
                if (strlen($params)) {
                    $params .= "&{$k}={$v}";
                } else {
                    $params .= "?{$k}={$v}";
                }
            }
            return redirect($url.$params);
        }
        if ($this->needOuath($path)) {
            // 需要认证
            $application = new Application(EasyWechat::getOptions());
            $thisUrl = append_uniqid($request->url(), Session::get('wechat_uniqid'));
            $thisUrl .= '&domain=' . $currentDomain;
            foreach ($request->all() as $k => $v) {
                if (in_array($k, ['wechat_uniqid', 'domain'])) {
                    continue;
                }
                $thisUrl .= "&{$k}={$v}";
            }
            return $response = $application
                ->oauth
                ->scopes(['snsapi_userinfo'])
                ->redirect("http://{$wechatDomain}/wechat/oauth?redirect_url=" . urlencode($thisUrl));
        }

        return $next($request);
    }


    private function prepare($request)
    {
        // 处理uniqid
        if (!empty($request->wechat_uniqid)) {
            Session::put('wechat_uniqid', $request->wechat_uniqid);
        }
        if (null === Session::get('wechat_uniqid')) {
            $uniqid = uniqid('', true);
            Session::put('wechat_uniqid', $uniqid);
        }
        // 处理openid
        if (empty(Session::get('wechat_openid'))) {
            $uniqidOpenid = UniqidOpenid::query()
                ->where('uniqid', Session::get('wechat_uniqid'))
                ->first();
            if (null !== $uniqidOpenid) {
                Session::put('wechat_openid', $uniqidOpenid->openid);
            }
        }
        // 处理member
        if (null === Session::get('member') && (null !== Session::get('wechat_openid'))) {
            $member = Member::query()
                ->where('openid', Session::get('wechat_openid'))
                ->first();
            if (null !== $member) {
                Session::put('member', $member);
            }
        }
    }

    /**
     * 是否需要经过微信认证
     * @return bool
     */
    private function needOuath($path) : bool
    {
        if (null === Session::get('wechat_openid')) {
            return true;
        }
        if (null === Session::get('member') && $path != 'wechat/upload') {
            return true;
        }
        return false;
    }
}
